package com.yh.jandan.ext ;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpHost;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;
import com.jfinal.log.Log4jLog;
import com.yh.jandan.controller.JandanController;
import com.yh.jandan.http.HttpUtil;
import com.yh.jandan.model.Meizi;
import com.yh.jandan.util.DateUtils;
import com.yh.jandan.util.MD5Util;

public class LocalApp {
	Log log = Log4jLog.getLog ( LocalApp.class ) ;

	private static int size = 0 ;

	public static void main ( String[] args ) {
		LocalApp.autocatch ( ) ;
	}

	private LocalApp ( ) {
	}

	public void get ( ) {
		Document doc = null ;
		HttpUtil httpUtil = new HttpUtil ( ) ;
		HttpHost proxy = buildProxy ( PropKit.use ( WebApp._CONFIG_ ).get ( "proxy" ) ) ;
		if ( null != proxy ) httpUtil.addProxy ( proxy ) ;
		int currentPage = get_current_page ( httpUtil ) ;
		try {
			getMeizis ( doc ) ;
			sleepRedom ( 20 , 20 ) ;
		} catch ( Exception e1 ) {
			e1.printStackTrace ( ) ;
		}
		try {
			do {
				try {
					String strPage = getPageTlp ( --currentPage ) ;
					doc = getDoc ( httpUtil , strPage ) ;
					getMeizis ( doc ) ;
					sleepRedom ( 20 , 20 ) ;
				} catch ( Exception e ) {
					e.printStackTrace ( ) ;
				}
			} while ( size-- > 0 ) ;
		} catch ( Exception e ) {
			e.printStackTrace ( ) ;
		} finally {
			if ( null != doc ) doc = null ;
			if ( null != httpUtil ) httpUtil.close ( ) ;
		}
	}

	private int get_current_page ( HttpUtil httpUtil ) {
		Document doc = null ;
		String url = "http://jandan.net/ooxx" , current_page = "2345" ;
		int i = 0 ;
		while ( true ) {
			if ( i++ > 10 ) break ;
			try {
				doc = getDoc ( httpUtil , url ) ;
				current_page = doc.select ( "span.current-comment-page" ).first ( ).text ( ) ;
				current_page = current_page.replace ( "[" , "" ).trim ( ) ;
				current_page = current_page.replace ( "]" , "" ).trim ( ) ;
				break ;
			} catch ( Exception e ) {
				e.printStackTrace ( ) ;
				sleepRedom ( 20 , 20 ) ;
			}
		}
		return Integer.parseInt ( current_page ) ;
	}

	private HttpHost buildProxy ( String proxyStr ) {
		if ( proxyStr == null || proxyStr.trim ( ).length ( ) < 1 ) return null ;
		proxyStr = proxyStr.trim ( ).replace ( " " , "" ) ;
		log.info ( "proxyStr=" + proxyStr ) ;
		return new HttpHost ( proxyStr ) ;
	}

	private void sleepRedom ( int min , int max ) {
		try {
			int i = min + (int) (Math.random ( ) * max) + 1 ;
			System.out.println ( "sleepRedom():[" + i + "seconds]" ) ;
			log.info ( "sleepRedom():[" + i + "seconds]" ) ;
			Thread.sleep ( i * 1000 ) ;
		} catch ( Exception e ) {
			e.printStackTrace ( ) ;
		}

	}

	private void getMeizis ( Document doc ) {
		Elements ees = doc.select ( "#comments" ).select ( ".commentlist" ).first ( ).children ( ) ;
		// int i = 0;
		Meizi meizi = null ;
		Element e = null ;
		for ( Element ee : ees ) {
			try {
				e = ee.select ( ".text" ).select ( "p" ).first ( ) ;
				if ( null == e ) continue ;
				// System.out.println( ++i + ":" + e );
				String href = e.select ( "a.view_img_link" ).attr ( "href" ) ;
				String src = e.select ( "img" ).first ( ).attr ( "src" ) ;
				// /
				meizi = new Meizi ( ) ;
				meizi.setSmall ( src ) ;
				meizi.setBig ( href ) ;
				meizi.setNote ( "" ) ;
				// meizi.setShow ( "true" ) ; //default true
				meizi.setMd5 ( getMd5 ( src ) ) ;
				meizi.setCreatedate ( new Date ( ) ) ;
				meizi.setWebsite ( "jandan" ) ;
				// /
				if ( exists ( meizi ) ) continue ;
				// /
				meizi.save ( ) ;
				// /
				System.out.println ( "save:" + meizi ) ;
				log.info ( "save:" + meizi.toJson ( ) ) ;
				// /
			} catch ( Exception e1 ) {
				e1.printStackTrace ( ) ;
			} finally {
				meizi = null ;
			}
		}
	}

	public static LocalApp getLocalApp ( ) {
		return new LocalApp ( ) ;
	}

	private static boolean isRunning = false ;

	public void start ( ) {
		if ( isRunning ) return ;
		isRunning = true ;
		new Thread ( new Thread_Jandan ( ) ).start ( ) ;
	}

	class Thread_Jandan implements Runnable {
		public void run ( ) {
			get ( ) ;
			isRunning = false ;
		}
	}

	private String getMd5 ( String src ) {
		return MD5Util.MD5 ( src ) ;
	}

	private String date2str ( Date date ) {
		return DateUtils.getDateByFormat ( date , DateUtils.YMDHMS_FORMAT ) ;
	}

	private String getPageTlp ( int page ) {
		return "http://jandan.net/ooxx/page-" + page + "#comments" ;
	}

	private boolean exists ( Meizi meizi ) {
		// int i = Meizi.dao.find( "select * from meizi where url=?" ,
		// meizi.getSmall() ).size();
		int i = Meizi.dao.find ( "select md5 from meizi where md5=?" , meizi.getMd5 ( ) ).size ( ) ;
		return i > 0 ;
	}

	private Document getDoc ( HttpUtil httpUtil , String url ) throws IOException {
		System.out.println ( "getDoc():" + url ) ;
		log.info ( "getDoc():" + url ) ;
		String html = httpUtil.GET ( url , buildHeader ( ) ).getHtml ( ) ;
		// log.info ( "getDoc():" +html );
		// System.out.println(html);
		return org.jsoup.Jsoup.parse ( html ) ;
	}

	private Map<String, String> buildHeader ( ) {
		Map<String, String> header = new HashMap<String, String> ( ) ;
		header.put ( "Accept-Encoding" , "identity" ) ; // 如果是乱码,就换这个./不压缩
		// header.put ( "Accept-Encoding" , "deflate, sdch" );
		// header.put( "Accept-Encoding" , "gzip, deflate, sdch" ); //压缩支持
		header.put ( "Host" , "jandan.net" ) ;
		String cookie = getCookie ( ) ;
		log.info ( "cookie():" + cookie ) ;
		header.put ( "Cookie" , cookie ) ;
		// header.put ( "Cookie" ,//
		// "PHPSESSID=tlbgkji3vd8u06bcmqtokrfn81;"//
		// + " 1661833985=0eedGP4txJ6cz2JiRoe4h%2FQcg8%2B6wTx7Bbu029Nu;"//
		// + " jdna=596e6fb28c1bb47f949e65e1ae03f7f5#1467362906495;"//
		// + " _ga=GA1.2.1792547255.1460632068;"//
		// +
		// " Hm_lvt_fd93b7fb546adcfbcf80c4fc2b54da2c=1466160853,1466683068,1467343016,1467360997;"//
		// + " Hm_lpvt_fd93b7fb546adcfbcf80c4fc2b54da2c=1467362910" );
		return header ;
	}

	int md5Time = (int) (new Date ( ).getTime ( )) % 20 ;

	private String getCookie ( ) {
		String md5 = getMd5 ( new Date ( ).getTime ( ) + "" , md5Time++ ).toLowerCase ( ) ;
		StringBuffer sb = new StringBuffer ( ) ;
		sb.append ( "PHPSESSID=" ).append ( getMd5 ( new Date ( ).getTime ( ) + "" , md5Time++ ).substring ( 7 ).toLowerCase ( ) + ";" ) ;
		sb.append ( "16" + (new Date ( ).getTime ( ) + "").substring ( 2 ) + "="
				+ (getMd5 ( new Date ( ).getTime ( ) + "" , md5Time++ ) + "" + getMd5 ( new Date ( ).getTime ( ) + "" , md5Time++ )).substring ( 19 ) + ";" ) ;
		sb.append ( " jdna=" + getMd5 ( new Date ( ).getTime ( ) + "" , md5Time++ ) + "#" + new Date ( ).getTime ( ) + ";" ) ;
		sb.append ( "_ga=" + "GA1.2." + ("17" + (new Date ( ).getTime ( ) + "").substring ( 2 ) + "." + new Date ( ).getTime ( ) + ";") ) ;
		sb.append ( "Hm_lvt_" + md5 + "=" + new Date ( ).getTime ( ) + "," + (new Date ( ).getTime ( ) + (new Date ( ).getTime ( )) % 200000 + 10000) + ","
				+ (new Date ( ).getTime ( ) + (new Date ( ).getTime ( )) % 3000000 + 1000000) + "," + (new Date ( ).getTime ( ) % 6000000 + 2000000) + ";" ) ;
		sb.append ( "Hm_lpvt_" + md5 + "=" + (new Date ( ).getTime ( ) % 6000000 + 2000000) + ";" ) ;
		return sb.toString ( ) ;
	}

	private String getMd5 ( String str , int times ) {
		return MD5Util.MD5 ( str , times ) ;
	}

	static {
		setSize ( 2 ) ;
	}

	public static void setSize ( int size ) {
		LocalApp.size = size ;
	}

	static boolean is_autocatch_ing = false ;

	public static void stop ( ) {
		JandanController.autocatch = false ;
	}

	public static void autocatch ( ) {
		if ( !JandanController.autocatch ) return ;
		if ( is_autocatch_ing ) return ;
		is_autocatch_ing = true ;

		catch_jandan ( ) ;

	}

	private static void catch_jandan ( ) {
		new Thread ( new Runnable ( ) {
			public void run ( ) {
				LocalApp localApp = getLocalApp ( ) ;
				try {
					do {
						localApp.start ( ) ;
						localApp.sleepRedom ( 2000 , 1000 ) ;
					} while ( JandanController.autocatch ) ;
				} catch ( Exception e ) {
					e.printStackTrace ( ) ;
				} finally {
					localApp = null ;
					is_autocatch_ing = false ;
				}
			}
		} ).start ( ) ;
	}
}
